<template>
  <div id="wrap">
    <h1>effectScope案例3</h1>
    <div v-if="isShow">
      <h3>countA:{{ abc.countA }}</h3>
      <h3>countA:{{ abc.countB }}</h3>
      <button @click="abc.incrementA">incrementA</button>
      <button @click="abc.incrementB">incrementB</button>
      <button @click="stopScope">销毁作用域</button>
    </div>
    <hr />

    <div v-show="isStopped">
      <h3>计数器的作用已经销毁成功</h3>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, type Ref, EffectScope, effectScope, onScopeDispose } from 'vue';

//定义返回对象的类型
interface classA {
  countA: Ref<number>;
  countB: Ref<number>;
  incrementA: () => void;
  incrementB: () => void;
}

let scope: EffectScope; //用于存储effectScope实例
const isShow: Ref<boolean> = ref(false);
console.log(isShow);

//创建effectScope实例
function setupScope(): Promise<classA> {
  scope = effectScope(); //创建一个新的作用域

  return new Promise((resolve) => {
    //在该作用域种运行所有的响应式状态
    let timer1: ReturnType<typeof setInterval>;
    let timer2: ReturnType<typeof setInterval>;
    scope.run(() => {
      const countA = ref(1);
      const countB = ref(2);
      const incrementA = () => {
        timer1 = setInterval(() => {
          countA.value++;
        }, 100);
      };
      const incrementB = () => {
        timer2 = setInterval(() => {
          countB.value++;
        }, 100);
      };
      //注册一个清理回调，当作用于被停止时调用
      onScopeDispose(() => {
        clearInterval(timer1);
        clearInterval(timer2);
        console.log('作用域已经停止，清理资源');
      });
      //返回需要在模板中使用的状态
      resolve({ countA, countB, incrementA, incrementB });
    });
  });
}
//初始值
let abc: classA;
const initScope = async () => {
  //调用setupScope，初始化作用域种的状态
  abc = await setupScope();
  console.log(abc.countA.value);
  isShow.value = true;
};
//停止作用域的函数
const isStopped = ref(false);
function stopScope() {
  if (scope) {
    scope.stop(); //停止作用域并触发销毁回调
    isStopped.value = true; //显式的表明作用域销毁
  }
}
initScope();
</script>
